M64 Features,
M64 Parser.
In M64, we have the
header, the
track and
music event table, the header is the beginning of the M64, what all M64s must have, it contains necessary information about the M64, like the NLST, amount of channels, tempo and master volume.
HEADER FORMAT AND COMMAND TABLE
Status Byte
| Parameters | Description
|
0x90 - 0x9F
| Offset (2 bytes)
| Points to track data for a specific channel, indicated by the second nibble of status byte. |
0xD3
| 1 byte
| Sequence type 80 for variable sequence, 0x00 - 0x25 for bank 00 to 37or 20. 60 is used for the 'Mario sounds' sequence.
|
0xD6
| Channels (16 bits)
| Disable channels flag. Each bit = one channel.
|
0xDB
| Master Volume (1 byte)
| Master Volume (unsigned integer).
|
0xDD
| Tempo in BMP (1 byte)
| Tempo setting (BPM).
|
0xD5 | 16 bits
| Not sure. Used in the very beggining of sequences (before channel enable flag). |
0xD7
| Channels (16 bits) | Enable channels flag. Each bit = one channel. |
0xFD
| Variable-length (1 or 2 bytes)
| Timestamp (used between track chunks and to ensure right looping).
|
0xFB
| Offset (2 bytes)
| Loop from the specified offset.
|
0xFF
| No param
| End of header
|
TRACKER FORMAT AND COMMAND TABLE
Status Byte
| Parameters | Description
|
0x90 - 0x9F
| Offset (2 bytes)
| Loads music data (divided in "layers"). Since simultaneous notes (using a "0" timestamp) aren't possible, many layers are loaded and played simultaneously. The second nibble of the status byte indicates the layer number.
|
0xC1
| Program (1 byte)
| "Set program" related. There isn't a master index for instruments, this seems to refer to the current set of instruments, which is not specified in the sequence data but loaded by something external to it.
Drums tracks usually use program 0x7f (127).
|
0xC2 | Transposition (1 signed byte)
| Transposition in semitones. |
0xC4 | No Param.
| Mark the beggining of track data.
|
0xD3 | Fine tune (1 byte)
| signed integer, can also be used for transposition events
|
0xD4 | Reverb (1 byte)
| Amount of reverb for the track (1 byte)
|
0xD8 | Vibrato (1 byte)
| Vibrato range
|
0xDC
| Priority (1 byte)
| Usually set on drum tracks if there's too much things playing so Sound effects can be used on that channel |
0xDD
| Pan (1 byte)
| Set pan for this track (01 = left, 64 = center, 127 = right)
|
0xDF
| Track Volume (1 bytes)
| Volume for this track (unsigned integer).
|
0xFD
| Variable-length (1 or 2 bytes)
| Timestamp (used between track chunks and to ensure right looping).
|
0xFF
| No Param
| End of Track Data
|
MUSIC FORMAT AND COMMAND TABLE
Status Byte
| Parameters | Description
|
0x00-0x3F | Timestamp (1 or 2 bytes) Velocity (1 byte) Duration (1 byte)
| "Play Note" commands ('Type 0'). Unlike MIDI, 0 = A0. Timestamp is variable lenght (see below). Duration byte seems to be timestamp before "NoteOff"
|
0x40-0x7F
| Timestamp (1 or 2 bytes) Velocity (1 byte) | "Play Note" commands ('Type 1') Duration = previous specified (producing more compact data).
|
0x80-0xBF | Velocity (1 byte) Duration (1 byte)
| "Play Note" commands ('Type 2'). Timestamp = previous specified (producing more compact data).
|
0xC0 | Timestamp (1 or 2 bytes)
| Timestamp used for rests.
|
0xC2 | Transposition (1 byte)
| Transposition in semitones. Since the 'PlayNote' commands just cover a range of 0x40 notes (as opposed to 0x7F possible MIDI notes), this is used to shift the range when needed.
|
0xE0 - E8 | ? | ? |
0xFC | 2 bytes
| Jump (used for loops). There isn't a loop counter, so the command is repeated. Offset is relative to individual sequence start.
|
0xFF | No Param.
| End of music track / Return from jump
|
Playnote velocity goes up to 0xFF but it usually doesn't overclock 0x64.
Gone for a while.